    .align          4
    .globl          celt_pitch_xcorr_asm
    .type           celt_pitch_xcorr_asm, @function

celt_pitch_xcorr_asm:
    addi            sp, sp, -64
    sw              s1, 56(sp)
    sw              s2, 52(sp)
    sw              s3, 48(sp)
    sw              s4, 44(sp)
    sw              s5, 40(sp)
    sw              s6, 36(sp)
    sw              s7, 32(sp)
    sw              s8, 28(sp)
    sw              s9, 24(sp)
    sw              s10, 20(sp)
    sw              s11, 16(sp)

    addi            a5, x0, 1              //maxcorr=1
    addi            a3, a3, -4             //len -= 4
    srai            s7, a3, 3              //len >> 3
    andi            a3, a3, 7              //len & 7
    srai            s9, a4, 2              //max_pitch / 4
    andi            a4, a4, 3              //max_pitch & 3
    mv              s11, a0
    mv              t0, a1

    beq             s9, x0, xcorr_asm_loop_m_exit
    mv              s10, x0                //loop_m = 0
xcorr_asm_loop_m:
    mv              a0, s11
    slli            s5, s10, 3
    add             a1, t0, s5
    addi            s1, x0, 0              //sum0 = 0
    addi            s2, x0, 0              //sum1 = 0
    addi            s3, x0, 0              //sum2 = 0
    addi            s4, x0, 0              //sum3 = 0
    lwia            a6, (a0), 1, 2         //x_data_v0_old
    lwia            a7, (a0), 1, 2         //x_data_v1_old
    lwia            t1, (a1), 1, 2         //y_data_v0_old
    lwia            t2, (a1), 1, 2         //y_data_v1_old
    kmada           s1, a6, t1
    kmada           s1, a7, t2

    beq             s7, x0, xcorr_asm_loop_m_0
    addi            s8, x0, 0              //loop_x = 0

xcorr_asm_loop_x:
    lwia            t3, (a0), 1, 2         //x_data_v0_new
    lwia            t4, (a0), 1, 2         //x_data_v1_new
    lwia            t5, (a1), 1, 2         //y_data_v0_new
    lwia            t6, (a1), 1, 2         //y_data_v1_new
    kmada           s1, t3, t5
    pkbt16          s5, t2, t1
    pkbt16          s6, t5, t2
    kmada           s1, t4, t6
    kmada           s2, a6, s5
    kmada           s3, a6, t2
    pkbt16          s5, t5, t2
    kmada           s2, a7, s6
    kmada           s3, a7, t5
    kmada           s4, a6, s5
    pkbt16          s6, t6, t5
    lwia            a6, (a0), 1, 2         //x_data_v0_old
    kmada           s4, a7, s6

    lwia            a7, (a0), 1, 2         //x_data_v1_old
    lwia            t1, (a1), 1, 2         //y_data_v0_old
    lwia            t2, (a1), 1, 2         //y_data_v1_old
    kmada           s1, a6, t1
    pkbt16          s5, t6, t5
    pkbt16          s6, t1, t6
    kmada           s1, a7, t2
    kmada           s2, t3, s5
    pkbt16          s5, t1, t6
    kmada           s3, t3, t6
    kmada           s2, t4, s6
    kmada           s4, t3, s5
    kmada           s3, t4, t1
    pkbt16          s6, t2, t1
    kmada           s4, t4, s6

    addi            s8, s8, 1
    blt             s8, s7, xcorr_asm_loop_x

xcorr_asm_loop_m_0:
    srai            s5, a3, 2
    beq             s5, x0, xcorr_asm_eq_0
    lwia            t3, (a0), 1, 2         //x_data_v0_new
    lwia            t4, (a0), 1, 2         //x_data_v1_new
    lwia            t5, (a1), 1, 2         //y_data_v0_new
    lwia            t6, (a1), 1, 2         //y_data_v1_new
    kmada           s1, t3, t5
    pkbt16          s5, t2, t1
    pkbt16          s6, t5, t2
    kmada           s2, a6, s5
    kmada           s1, t4, t6
    kmada           s3, a6, t2
    kmada           s2, a7, s6
    pkbt16          s5, t5, t2
    kmada           s3, a7, t5
    kmada           s4, a6, s5
    pkbt16          s6, t6, t5
    mv              a6, t3                 //x_data_v0_old
    kmada           s4, a7, s6

    mv              a7, t4                 //x_data_v1_old
    mv              t1, t5                 //y_data_v0_old
    mv              t2, t6                 //y_data_v1_old
xcorr_asm_eq_0:
    andi            s5, a3, 3
    beq             s5, x0, xcorr_asm_end_eq_0
    addi            s6, x0, 1
    beq             s5, s6, xcorr_asm_end_eq_1
    addi            s6, x0, 2
    beq             s5, s6, xcorr_asm_end_eq_2
    addi            s6, x0, 3
    beq             s5, s6, xcorr_asm_end_eq_3

xcorr_asm_end_eq_0:
    lwia            t5, (a1), 1, 2
    lhu             t6, 0(a1)
    pkbt16          s5, t2, t1
    kmada           s2, a6, s5
    pkbt16          s6, t5, t2
    kmada           s3, a6, t2
    kmada           s2, a7, s6
    pkbt16          s5, t5, t2
    kmada           s3, a7, t5
    kmada           s4, a6, s5
    pkbt16          s6, t6, t5
    kmada           s4, a7, s6
    j               xcorr_asm_end_store

xcorr_asm_end_eq_1:
    lh              t3, 0(a0)
    lwia            t5, (a1), 1, 2
    lwia            t6, (a1), 1, 2
    kmabb           s1, t3, t5
    pkbt16          s5, t2, t1
    kmada           s2, a6, s5
    pkbt16          s6, t5, t2
    kmada           s2, a7, s6
    kmada           s3, a6, t2
    kmabt           s2, t3, t5
    kmada           s3, a7, t5
    pkbt16          s5, t5, t2
    kmabb           s3, t3, t6
    kmada           s4, a6, s5
    pkbt16          s6, t6, t5
    kmada           s4, a7, s6
    kmabt           s4, t3, t6
    j               xcorr_asm_end_store

xcorr_asm_end_eq_2:
    lw              t3, 0(a0)
    lwia            t5, (a1), 1, 2
    lwia            t6, (a1), 1, 2
    lh              t4, 0(a1)
    kmada           s1, t3, t5
    pkbt16          s5, t2, t1
    kmada           s2, a6, s5
    pkbt16          s6, t5, t2
    kmada           s3, a6, t2
    kmada           s2, a7, s6
    pkbt16          s5, t6, t5
    kmada           s3, a7, t5
    kmada           s2, t3, s5
    kmada           s3, t3, t6
    pkbt16          s5, t5, t2
    kmada           s4, a6, s5
    pkbt16          s6, t6, t5
    kmada           s4, a7, s6
    pkbt16          s5, t4, t6
    kmada           s4, t3, s5
    j               xcorr_asm_end_store

xcorr_asm_end_eq_3:
    lwia            t3, (a0), 1, 2
    lhu             t4, 0(a0)
    lwia            t5, (a1), 1, 2
    lwia            t6, (a1), 1, 2
    kmada           s1, t3, t5
    pkbt16          s5, t2, t1
    kmada           s1, t4, t6
    pkbt16          s6, t5, t2
    kmada           s2, a6, s5
    pkbt16          s5, t6, t5
    kmada           s2, a7, s6
    kmada           s3, a6, t2
    kmada           s2, t3, s5
    kmada           s3, a7, t5
    kmabt           s2, t4, t6
    pkbt16          s5, t5, t2
    kmada           s4, a6, s5
    pkbt16          s6, t6, t5
    kmada           s4, a7, s6
    lwia            a6, (a1), 1, 2
    kmada           s3, t3, t6
    pkbt16          s5, a6, t6
    kmada           s4, t3, s5
    kmada           s3, t4, a6
    kmabt           s4, t4, a6

xcorr_asm_end_store:
    swia            s1, (a2), 1, 2
    swia            s2, (a2), 1, 2
    swia            s3, (a2), 1, 2
    swia            s4, (a2), 1, 2
    maxw            a5, a5, s1
    maxw            a5, a5, s2
    maxw            a5, a5, s3
    maxw            a5, a5, s4

    addi            s10, s10, 1
    blt             s10, s9, xcorr_asm_loop_m

xcorr_asm_loop_m_exit:
    beq             a4, x0, xcorr_asm_exit
    addi            s6, x0, 1
    beq             a4, s6, xcorr_asm_exit_1
    addi            s6, x0, 2
    beq             a4, s6, xcorr_asm_exit_2
    addi            s6, x0, 3
    beq             a4, s6, xcorr_asm_exit_3

xcorr_asm_exit_1:
    slli            s6, s9, 3
    add             a1, t0, s6
    mv              a0, s11
    mv              s10, x0
    slli            s5, s7, 3
    add             s5, s5, a3
    addi            s5, s5, 4
    mv              s1, x0
xcorr_asm_exit_1_loop:
    lhia            a6, (a0), 1, 1
    lhia            t1, (a1), 1, 1
    addi            s10, s10, 1
    kmabb           s1, a6, t1
    blt             s10, s5, xcorr_asm_exit_1_loop
    maxw            a5, a5, s1
    swia            s1, (a2), 1, 2
    j               xcorr_asm_exit

xcorr_asm_exit_2:
    slli            s6, s9, 3
    add             a1, t0, s6
    mv              a0, s11
    mv              s10, x0
    slli            s5, s7, 3
    add             s5, s5, a3
    addi            s5, s5, 4
    mv              s1, x0
xcorr_asm_exit_2_1_loop:
    lhia            a6, (a0), 1, 1
    lhia            t1, (a1), 1, 1
    addi            s10, s10, 1
    kmabb           s1, a6, t1
    blt             s10, s5, xcorr_asm_exit_2_1_loop
    maxw            a5, a5, s1
    swia            s1, (a2), 1, 2

    slli            s6, s9, 3
    add             a1, t0, s6
    addi            a1, a1, 2
    mv              a0, s11
    mv              s10, x0
    slli            s5, s7, 3
    add             s5, s5, a3
    addi            s5, s5, 4
    mv              s1, x0
xcorr_asm_exit_2_2_loop:
    lhia            a6, (a0), 1, 1
    lhia            t1, (a1), 1, 1
    addi            s10, s10, 1
    kmabb           s1, a6, t1
    blt             s10, s5, xcorr_asm_exit_2_2_loop
    maxw            a5, a5, s1
    swia            s1, (a2), 1, 2

    j               xcorr_asm_exit

xcorr_asm_exit_3:
    slli            s6, s9, 3
    add             a1, t0, s6
    mv              a0, s11
    mv              s10, x0
    slli            s5, s7, 3
    add             s5, s5, a3
    addi            s5, s5, 4
    mv              s1, x0
xcorr_asm_exit_3_1_loop:
    lhia            a6, (a0), 1, 1
    lhia            t1, (a1), 1, 1
    addi            s10, s10, 1
    kmabb           s1, a6, t1
    blt             s10, s5, xcorr_asm_exit_3_1_loop
    maxw            a5, a5, s1
    swia            s1, (a2), 1, 2

    slli            s6, s9, 3
    add             a1, t0, s6
    addi            a1, a1, 2
    mv              a0, s11
    mv              s10, x0
    slli            s5, s7, 3
    add             s5, s5, a3
    addi            s5, s5, 4
    mv              s1, x0
xcorr_asm_exit_3_2_loop:
    lhia            a6, (a0), 1, 1
    lhia            t1, (a1), 1, 1
    addi            s10, s10, 1
    kmabb           s1, a6, t1
    blt             s10, s5, xcorr_asm_exit_3_2_loop
    maxw            a5, a5, s1
    swia            s1, (a2), 1, 2

    slli            s6, s9, 3
    add             a1, t0, s6
    addi            a1, a1, 4
    mv              a0, s11
    mv              s10, x0
    slli            s5, s7, 3
    add             s5, s5, a3
    addi            s5, s5, 4
    mv              s1, x0
xcorr_asm_exit_3_3_loop:
    lhia            a6, (a0), 1, 1
    lhia            t1, (a1), 1, 1
    addi            s10, s10, 1
    kmabb           s1, a6, t1
    blt             s10, s5, xcorr_asm_exit_3_3_loop
    maxw            a5, a5, s1
    swia            s1, (a2), 1, 2

xcorr_asm_exit:
    mv              a0, a5
    lw              s1, 56(sp)
    lw              s2, 52(sp)
    lw              s3, 48(sp)
    lw              s4, 44(sp)
    lw              s5, 40(sp)
    lw              s6, 36(sp)
    lw              s7, 32(sp)
    lw              s8, 28(sp)
    lw              s9, 24(sp)
    lw              s10, 20(sp)
    lw              s11, 16(sp)
    addi            sp, sp, 64
    ret
